# ommbot/ircevent.py
#
#
# http://www.irchelp.org/irchelp/rfc/rfc2812.txt

""" this module contains the Ircevent class """

__copyright__ = 'this file is in the public domain'

from ommbot.generic import ircdecode
import time
import re

class Ircevent(object):

    """ represents an irc event """
    
    def __init__(self):
        self.cmnd = None
        self.prefix = "" # text before cmnd
        self.postfix = "" # text between cmnd and first ":" 
        self.target = ""
        self.arguments = []
        self.nick = ""
        self.user = ""
        self.ruserhost = ""
        self.userhost = ""
        self.channel = ""
        self.origtxt = ""
        self.txt = ""
        self.time = time.time()
        self.msg = None 
        self.args = []
        self.rest = ""
        self.usercmnd = 0
        self.bot = None
        self.sock = None
        self.queues = []
        self.printto = None
        self.speed = 5
        self.options = []
        self.groups = None

    def __str__(self):
        return "cmnd=%s prefix=%s postfix=%s arguments=%s nick=%s user=%s \
userhost=%s channel=%s txt=%s args=%s rest=%s speed=%s" % (self.cmnd, \
self.prefix, self.postfix, self.arguments, self.nick, self.user, \
self.userhost, self.channel, self.txt, self.args, self.rest, self.speed)

    def copyin(self, ievent):
        """ copy ievent """
        self.cmnd = str(ievent.cmnd)
        self.prefix = str(ievent.prefix)
        self.postfix = str(ievent.postfix)
        self.target = str(ievent.target)
        self.arguments = list(ievent.arguments)
        self.nick = str(ievent.nick)
        self.user = str(ievent.user)
        self.userhost = str(ievent.userhost)
        self.channel = str(ievent.channel)
        self.origtxt = str(ievent.origtxt)
        self.txt = str(ievent.txt)
        self.time = ievent.time
        self.msg = ievent.msg
        self.args = list(ievent.args)
        self.rest = str(ievent.rest)
        self.usercmnd = ievent.usercmnd
        self.bot = ievent.bot
        self.sock = ievent.sock
        self.printto = ievent.printto
        self.speed = int(ievent.speed)
        self.queues = list(ievent.queues)
        self.options = list(ievent.options)
        self.makeargrest()

    def makeargrest(self):
        """ create ievent.args and ievent.rest """
        try:
            self.args = self.txt.split()[1:]
        except ValueError:
            self.args = []
        try:
            cmnd, self.rest = self.txt.split(' ', 1)
        except ValueError:
            self.rest = ""

    def parse(self, bot, rawstr):
        """ parse raw string into ircevent """
        rawstr = rawstr.strip()
        splitted = re.split('\s', rawstr)
        # check if there is a prefix (: in front)
        if rawstr[0] == ':':
            self.prefix = splitted[0][1:]
            self.cmnd = splitted[1]
            # get nick/userhost
            nickuser = self.prefix.split('!')
            if len(nickuser) == 2:
                self.nick = nickuser[0]
                self.userhost = nickuser[1]
        else:
            self.cmnd = splitted[0]
            self.arguments = splitted[1:]
            if self.arguments[0] and self.arguments[0].startswith(':'):
                self.txt = ' '.join(self.arguments)[1:]
            return self
        if self.arguments:
            self.target = self.arguments[0]
        if pfc.has_key(self.cmnd):
            self.arguments = splitted[2:pfc[self.cmnd]+2]
            self.txt = ' '.join(splitted[pfc[self.cmnd]+2:])
        else:
            self.arguments = splitted[2:]
        self.postfix = ' '.join(self.arguments)
        if self.target and self.target.startswith(':'):
            self.txt = ' '.join(self.arguments)
        if self.txt:
            if self.txt[0] == ":":
                self.txt = self.txt[1:]
        # do cmnd specific stuff
        if self.cmnd == 'PRIVMSG':
            self.channel = self.arguments[0]
        elif self.cmnd == 'JOIN':
            if self.txt:
                self.channel = self.txt
            else:
                self.channel = self.arguments[0]
        elif self.cmnd == 'PART':
            self.channel = self.postfix
        elif self.cmnd == 'MODE':
            self.channel = self.arguments[0]
        elif self.cmnd == 'KICK':
            self.channel = self.arguments[0]
        elif self.cmnd == '353':
            self.channel = self.arguments[2]
        elif self.cmnd == '324':
            self.channel = self.arguments[1]
        self.channel = self.channel.lower()
        self.ruserhost = str(self.userhost)
        if self.userhost:
            self.user = self.userhost.split('@')[0]
        # convert txt to ascii
        try:
            self.txt = self.txt.encode('ascii', 'ignore')
        except:
            pass
        self.txt = self.txt.strip()
        self.origtxt = str(self.txt)
        self.makeargrest()
        return self

    def reply(self, txt):
        """ reply txt .. first check if queue then if DCC then /msg 
            otherwise assume channel
        """
        if not self.bot:
            return
        if self.queues:
            for i in self.queues:
                i.put_nowait(txt)
            return
        if self.cmnd == 'DCC' and self.sock:
            txt = ircdecode(txt)
            self.sock.send(txt + '\n')
            return
        if self.printto:
            self.bot.say(self.printto, txt, fromm=self.nick)
            return
        if self.msg:
            self.bot.say(self.nick, txt, fromm=self.nick)
        else:
            self.bot.say(self.channel, txt, fromm=self.nick)
        
    def missing(self, txt):
        """ show whar arguments are missing """
        if self.origtxt:
            splitted = self.origtxt.split()
            if self.bot.nick in splitted[0]:
                self.reply(splitted[1] + ' ' + txt)
            else:
                self.reply(splitted[0] + ' ' + txt)
        else:
            self.reply('missing origtxt: %s' % txt)

# postfix count aka how many arguments

pfc = {}
pfc['NICK'] = 0
pfc['QUIT'] = 0
pfc['SQUIT'] = 1
pfc['JOIN'] = 0
pfc['PART'] = 1
pfc['TOPIC'] = 1
pfc['KICK'] = 2
pfc['PRIVMSG'] = 1
pfc['NOTICE'] = 1
pfc['SQUERY'] = 1
pfc['PING'] = 0
pfc['ERROR'] = 0
pfc['AWAY'] = 0
pfc['WALLOPS'] = 0
pfc['INVITE'] = 1
pfc['001'] = 1
pfc['002'] = 1
pfc['003'] = 1
pfc['004'] = 4
pfc['005'] = 15
pfc['302'] = 1
pfc['303'] = 1
pfc['301'] = 2
pfc['305'] = 1
pfc['306'] = 1
pfc['311'] = 5
pfc['312'] = 3
pfc['313'] = 2
pfc['317'] = 3
pfc['318'] = 2
pfc['319'] = 2
pfc['314'] = 5
pfc['369'] = 2
pfc['322'] = 3
pfc['323'] = 1
pfc['325'] = 3
pfc['324'] = 4
pfc['331'] = 2
pfc['332'] = 2
pfc['341'] = 3
pfc['342'] = 2
pfc['346'] = 3
pfc['347'] = 2
pfc['348'] = 3
pfc['349'] = 2
pfc['351'] = 3
pfc['352'] = 7
pfc['315'] = 2
pfc['353'] = 3
pfc['366'] = 2
pfc['364'] = 3
pfc['365'] = 2
pfc['367'] = 2
pfc['368'] = 2
pfc['371'] = 1
pfc['374'] = 1
pfc['375'] = 1
pfc['372'] = 1
pfc['376'] = 1
pfc['381'] = 1
pfc['382'] = 2
pfc['383'] = 5
pfc['391'] = 2
pfc['392'] = 1
pfc['393'] = 1
pfc['394'] = 1
pfc['395'] = 1
pfc['262'] = 3
pfc['242'] = 1
pfc['235'] = 3
pfc['250'] = 1
pfc['251'] = 1
pfc['252'] = 2
pfc['253'] = 2
pfc['254'] = 2
pfc['255'] = 1
pfc['256'] = 2
pfc['257'] = 1
pfc['258'] = 1
pfc['259'] = 1
pfc['263'] = 2
pfc['265'] = 1
pfc['266'] = 1
pfc['401'] = 2
pfc['402'] = 2
pfc['403'] = 2
pfc['404'] = 2
pfc['405'] = 2
pfc['406'] = 2
pfc['407'] = 2
pfc['408'] = 2
pfc['409'] = 1
pfc['411'] = 1
pfc['412'] = 1
pfc['413'] = 2
pfc['414'] = 2
pfc['415'] = 2
pfc['421'] = 2
pfc['422'] = 1
pfc['423'] = 2
pfc['424'] = 1
pfc['431'] = 1
pfc['432'] = 2
pfc['433'] = 2
pfc['436'] = 2
pfc['437'] = 2
pfc['441'] = 3
pfc['442'] = 2
pfc['443'] = 3
pfc['444'] = 2
pfc['445'] = 1
pfc['446'] = 1
pfc['451'] = 1
pfc['461'] = 2
pfc['462'] = 1
pfc['463'] = 1
pfc['464'] = 1
pfc['465'] = 1
pfc['467'] = 2
pfc['471'] = 2
pfc['472'] = 2
pfc['473'] = 2
pfc['474'] = 2
pfc['475'] = 2
pfc['476'] = 2
pfc['477'] = 2
pfc['478'] = 3
pfc['481'] = 1
pfc['482'] = 2
pfc['483'] = 1
pfc['484'] = 1
pfc['485'] = 1
pfc['491'] = 1
pfc['501'] = 1
pfc['502'] = 1
